package event

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"sync"

	"github.com/gorilla/websocket"
	"github.com/sirupsen/logrus"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

// WebSocket 连接管理器
type ConnManager struct {
	connections map[*websocket.Conn]bool
	sync.RWMutex
}

var connManager = ConnManager{
	connections: make(map[*websocket.Conn]bool),
}

var handlerEventManager *eventManager

func (cm *ConnManager) Add(conn *websocket.Conn) {
	cm.Lock()
	defer cm.Unlock()
	cm.connections[conn] = true
}

func (cm *ConnManager) Remove(conn *websocket.Conn) {
	cm.Lock()
	defer cm.Unlock()
	delete(cm.connections, conn)
}

func (cm *ConnManager) Broadcast(f *Frame) {
	cm.RLock()
	defer cm.RUnlock()
	for conn := range cm.connections {
		err := conn.WriteMessage(websocket.BinaryMessage, f.Serialize())
		if err != nil {
			log.Printf("Broadcast failed: %v", err)
			cm.Remove(conn)
		}
	}
}

// WebSocket 处理函数
var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool { return true },
}

func wsHandler(w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Printf("Upgrade failed: %v", err)
		return
	}
	defer conn.Close()

	connManager.Add(conn)
	defer connManager.Remove(conn)

	fmt.Println("new websocket connection: ", conn.RemoteAddr().String())

	for {
		// 读取 WebSocket 消息
		msgType, data, err := conn.ReadMessage()
		if err != nil {
			log.Printf("ReadMessage failed: %v", err)
			return
		}
		if msgType != websocket.BinaryMessage {
			continue
		}

		// 处理请求
		// go handleRequest(conn, data)
		handleRequest(conn, data)
	}
}

func writeErrorReply(conn *websocket.Conn, req *Frame, code int, message string) {
	f := NewRepError(req, code, message)
	conn.WriteMessage(websocket.BinaryMessage, f.Serialize())
}
func handleRequest(conn *websocket.Conn, data []byte) {
	var frame = &Frame{}
	f, err := DeserializeFrame(data)

	if err != nil {
		log.Printf("Failed to parse Frame: %v", err)
		writeErrorReply(conn, frame, errCodeContentError, err.Error())
		return
	} else {
		frame = f
	}

	fmt.Printf("recv frame: %v \n", frame)

	mgr := handlerEventManager
	if mgr == nil {
		mgr, err = GetGlobalEventManager()
	}
	if err != nil {
		log.Printf("Failed to get event manager: %v", err)
		writeErrorReply(conn, frame, errCodeInternalError, err.Error())
	}

	switch frame.Type {
	case get_event:
		req := ReqGetEvent{}
		if err := json.Unmarshal(data, &req); err != nil {
			writeErrorReply(conn, frame, errCodeContentError, err.Error())
			return
		}

		e, err := mgr.get(req.ID)
		if err != nil {
			writeErrorReply(conn, frame, errCodeGetEventFailed, err.Error())
			return
		}
		resp := NewRepGetEvent(frame, e)
		conn.WriteMessage(websocket.BinaryMessage, resp.Serialize())

	case get_events:
		req := &ReqGetEvents{}
		err := frame.DecodeData(req)
		if err != nil {
			writeErrorReply(conn, frame, errCodeContentError, err.Error())
			return
		}
		// 假设 getEvents 是一个函数，用于根据 ID 列表获取事件
		events, err := mgr.getArray(req.IDs)
		if err != nil {
			writeErrorReply(conn, frame, errCodeGetEventFailed, err.Error())
			return
		}
		resp := NewRepGetEvents(frame, events)
		conn.WriteMessage(websocket.BinaryMessage, resp.Serialize())

	case get_processing_events:
		// 假设 getProcessingEvents 是一个函数，用于获取正在处理的事件
		processingEvents := mgr.getProcessingEvents()
		resp := NewRepGetProcessingEvents(frame, processingEvents)
		conn.WriteMessage(websocket.BinaryMessage, resp.Serialize())

	case get_current_run_events:
		// 假设 getCurrentRunEvents 是一个函数，用于获取当前运行中的事件
		currentRunEvents, err := mgr.getCurrentRunEvents()
		if err != nil {
			writeErrorReply(conn, frame, errCodeGetEventFailed, err.Error())
			return
		}
		resp := NewRepGetCurrentRunEvents(frame, currentRunEvents)
		conn.WriteMessage(websocket.BinaryMessage, resp.Serialize())

	case get_current_run_event_ids:
		// 假设 getCurrentRunEventIds 是一个函数，用于获取当前运行中的事件 ID 列表
		eventIds, err := mgr.getCurrentRunIDs()
		if err != nil {
			writeErrorReply(conn, frame, errCodeGetEventFailed, err.Error())
			return
		}
		resp := NewRepGetCurrentRunEventIds(frame, eventIds)
		conn.WriteMessage(websocket.BinaryMessage, resp.Serialize())

	case get_all_run_ids:
		allRunIds, err := mgr.getAllRunIDs()
		if err != nil {
			writeErrorReply(conn, frame, errCodeGetEventFailed, err.Error())
			return
		}
		resp := NewRepGetAllRunIds(frame, allRunIds)
		conn.WriteMessage(websocket.BinaryMessage, resp.Serialize())

	case get_all_runs:
		allRuns, err := mgr.getAllRuns()
		if err != nil {
			writeErrorReply(conn, frame, errCodeGetEventFailed, err.Error())
			return
		}
		resp := NewRepGetAllRuns(frame, allRuns)
		conn.WriteMessage(websocket.BinaryMessage, resp.Serialize())

	case get_current_run_id:
		logrus.Info("Fetching current run ID")
		runId := mgr.getCurrentRunID()
		resp := NewRepGetCurrentRunID(frame, runId)
		conn.WriteMessage(websocket.BinaryMessage, resp.Serialize())

	case get_event_count:
		req := &ReqGetEventCount{}
		err := frame.DecodeData(req)
		if err != nil {
			writeErrorReply(conn, frame, errCodeContentError, err.Error())
			return
		}

		count, err := mgr.getCountForRun(req.RunID)
		if err != nil {
			writeErrorReply(conn, frame, errCodeGetEventFailed, err.Error())
			return
		}
		resp := NewRepGetEventCount(frame, count)
		conn.WriteMessage(websocket.BinaryMessage, resp.Serialize())

	case get_events_for_run:
		req := &ReqGetEventsForRun{}
		if err := frame.DecodeData(req); err != nil {
			writeErrorReply(conn, frame, errCodeContentError, err.Error())
			return
		}

		events, err := mgr.getEventsForRun(req.RunID, req.Offset, req.Cnt)
		if err != nil {
			writeErrorReply(conn, frame, errCodeGetEventFailed, err.Error())
			return
		}
		resp := NewRepGetEventsForRun(frame, events)
		conn.WriteMessage(websocket.BinaryMessage, resp.Serialize())

	case get_all_parents_children:
		req := &ReqGetAllParentsChildren{}
		if err := frame.DecodeData(req); err != nil {
			writeErrorReply(conn, frame, errCodeContentError, err.Error())
			return
		}
		var evts []Event = make([]Event, 0)

		// 递归获取事件的所有父节点和子节点

		evt, err := mgr.get(req.ID)
		if err != nil {
			writeErrorReply(conn, frame, errCodeGetEventFailed, err.Error())
			return
		}
		evts = append(evts, *evt)

		finishedIDs := make(map[string]struct{})
		finishedIDs[evt.ID] = struct{}{}

		for i := 0; i < len(evts); i++ {
			evt = &evts[i]
			ids := make([]string, 0)
			if evt.ParentID != "" {
				if _, ok := finishedIDs[evt.ParentID]; !ok {
					ids = append(ids, evt.ParentID)
				}
			}
			if evt.Children != nil {
				for _, childID := range evt.Children {
					if _, ok := finishedIDs[childID]; !ok {
						ids = append(ids, childID)
					}
				}
			}
			// 获取父节点和子节点
			pcs, err := mgr.getArray(ids)
			if err != nil {
				writeErrorReply(conn, frame, errCodeGetEventFailed, fmt.Sprintf("获取%s的父节点和子节点失败: %s", evt.ID, err.Error()))
				return
			}
			for _, pc := range pcs {
				evts = append(evts, *pc)
				finishedIDs[pc.ID] = struct{}{}
			}
		}
		resp := NewRepGetAllParentsChildren(frame, evts)
		conn.WriteMessage(websocket.BinaryMessage, resp.Serialize())
	default:
		// 返回错误响应
		resp := NewRepError(nil, errCodeUnknownRequest, "未知请求类型")
		conn.WriteMessage(websocket.BinaryMessage, resp.Serialize())
	}
}

type wsServer struct {
	*SimpleProcessor
	mgr *eventManager
}

func (p *wsServer) Process(e *Event) {
	e.AddListener(func(e *Event) {
		connManager.Broadcast(NewRepEventUpdate(e))
	})
}

var wsServerProcessor *wsServer

func newWSProcessor() EventProcessor {
	if wsServerProcessor == nil {
		mgr, err := GetGlobalEventManager()
		if err != nil {
			panic(err)
		}
		err = mgr.startNewRun()
		if err != nil {
			panic(err)
		}

		wsServerProcessor = &wsServer{
			SimpleProcessor: NewSimpleMiddleware("WebSocketServer", nil),
			mgr:             mgr,
		}
		// 设置 HTTP 服务
		http.HandleFunc("/ws", wsHandler)

		go func() {
			fmt.Println("Starting WebSocket server on :8080")
			if err := http.ListenAndServe(":8080", nil); err != nil {
				log.Fatal("ListenAndServe: ", err)
			}
		}()
	}
	return wsServerProcessor
}
func init() {
	registerDefaultPlugin("WebSocketServer", newWSProcessor)
}

func NewLocalDbFileServer(dbFilePath string, port int) error {
	// 检测数据库文件是否存在
	if _, err := os.Stat(dbFilePath); os.IsNotExist(err) {
		return err
	}
	// 初始化 SQLite 数据库
	db, err := gorm.Open(sqlite.Open(dbFilePath), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			SingularTable: true, // 使用单数表名
		},
	})
	if err != nil {
		return err
	}
	mgr, err := newEventManager(db)
	if err != nil {
		return err
	}
	mgr.db = db

	if handlerEventManager == nil {
		// 设置 HTTP 服务
		http.HandleFunc("/ws", wsHandler)
		go func() {
			host := fmt.Sprintf(":%d", port)
			fmt.Println("Starting WebSocket server on", host)
			if err := http.ListenAndServe(host, nil); err != nil {
				log.Fatal("ListenAndServe: ", err)
			}
		}()
	}
	handlerEventManager = mgr
	return nil
}
